package com.zy.design.pattern.template.jdbctm;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhaoyi
 * @date 2021/7/28 11:33
 * 基于模板方法
 * 简单的实现基本的 JdbcTemplate
 * <p>
 * 这里只是一个简单的流程
 */
public class MySimpleJdbcTemplate<T> {


    public List<T> query(String sql, Mapper<T> mapper) {
        //获取连接
        Connection conn = getConnection();
        Statement statement = null;
        try {
            statement = conn.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            return mapper.convert(resultSet);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    private Connection getConnection() {
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://10.0.10.54:3306/cia_test", "bftest", "bf@test2020");
        } catch (Exception e) {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ee) {
                    ee.printStackTrace();
                }
            }
            e.printStackTrace();
        }
        return conn;
    }


    public List<T> query2(String sql, Class<T> clz) {
        //获取连接
        Connection conn = getConnection();
        Statement statement = null;
        try {
            statement = conn.createStatement();
            ResultSet rs = statement.executeQuery(sql);
            List ls = new ArrayList();
            while (rs.next()) {
                T t = clz.newInstance();
                Field[] fields = clz.getDeclaredFields();

                for (Field f : fields) {
                    Class<?> type = f.getType();
                    if (type.equals(Integer.class)) {
                        Method m = clz.getMethod("set" + getMethodName(f.getName()), Integer.class);
                        m.invoke(t, rs.getInt(f.getName()));
                    }
                    if (type.equals(String.class)) {
                        Method m = clz.getMethod("set" + getMethodName(f.getName()), String.class);
                        m.invoke(t, rs.getString(f.getName()));
                    }
                }
                ls.add(t);
            }

            return ls;


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    private String getMethodName(String name) {
        byte[] items = name.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }
}
